﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CentaLine.DAL;
using CentaLine.Infrastructure;
using CentaLine.Model;

namespace CentaLine.Repository
{
    /// <summary>
    /// 虚拟电话分配操作相关
    /// </summary>
    public class VitualPhoneManager
    {
        //区董相关操作
        DirectorManager directorManager = new DirectorManager();
        //业务员相关操作
        CounselorManager counselorManager = new CounselorManager();

        VitualPhoneDAL VitualPhoneDAL = new VitualPhoneDAL();

        #region 自动分配->主程序入口
        /// <summary>
        /// 自动分配
        /// </summary>
        public CommResult AutoAssign()
        {
           
            DateTime applyMonth = DateTime.Now;//默认处理当前月份未处理的申请
            CommResult res = new CommResult();
            try
            {
                Stopwatch sp = new Stopwatch();
                sp.Start();
                res.Result = BackUpdialnumber();
                if (!res.Result)
                {
                    Logger.LogDB.Error("供应商虚拟真实电话备份失败");
                    res.Exception = "供应商虚拟真实电话备份失败";
                    return res;
                }

                res.Result = AsyncCounselorApplicationList(applyMonth);
                if (!res.Result)
                {
                    Logger.LogDB.Error("申报数据同步失败");
                    res.Exception = "申报数据同步失败";
                    return res;
                }

                //处理组织关系异动 以及离职 
                res.Result = InitalRemoteVitualPhone(applyMonth);
                if (!res.Result)
                {
                    Logger.LogDB.Error("处理组织关系异动以及离职状态失败");
                    res.Exception = "处理组织关系异动以及离职状态失败";
                    return res;
                }

                //更新本地区董目前虚拟号码已分配的虚拟号码的状态 
                //即供应商库中虚拟号码已释放的话 则本地库中虚拟号码也释放掉 (本地导入的虚拟电话又个状态 是否已分配，该状态 应该有供应商数据确认)
                res.Result = InitalVPStatusOfDirectors();
                if (!res.Result)
                {
                    Logger.LogDB.Error("本地虚拟电话数据初始化失败");
                    res.Exception = "本地虚拟电话数据初始化失败";
                    return res;
                }

                //获取所有区董信息
                List<Director> directorList = directorManager.GetDirectorInfoListWithVP().ToList();
                //处理和每位区董挂钩的申请信息
                directorList.ForEach(d => AssignForSingleDirector(applyMonth, d));

                //备份当前虚拟电话分配状态
                this.BackUpdVitualPhone();

                sp.Stop();
                Logger.Log.Info("本次服务总耗时:" + sp.Elapsed);

                res.Result = true;
                res.Message = "处理成功，本次耗时:" + sp.Elapsed;
            }
            catch (Exception e)
            {
                Logger.LogDB.Error("自动分配主程序", e);
                res.Result = false;
                res.Exception = e.ToString();
            }
            return res;
        }
        #endregion

        #region 根据总监分组,处理虚拟电话申请
        public void AssignForSingleDirector(DateTime applyMonth, Director director)
        {
            Stopwatch sp = new Stopwatch();
            sp.Start();
            //用于存储成功处理的申请信息列表
            List<CounselorApplication> successhandelList = new List<CounselorApplication>();
            //获取该区董当前申请月份对应所有未成功处理的申请列表
            List<CounselorApplication> list = directorManager.GetAllCounselorApplicationList(applyMonth, director.Id).ToList();
            List<CounselorApplication> unHandeledList = list.FindAll(c => c.IsEnabledHandelAgain == true);//可以处理的申请处理状态 
            //获取该区董目前所有可用的虚拟电话
            List<VitualPhone> VitualPhoneList = directorManager.GetAllUnUsedPhoneList(director.Id).ToList();

            //数据分析
            string appStr = "";
            string phoneStr = "";
            var appSumRes = unHandeledList.GroupBy(c => c.PhoneKind.Name).Select(g => new { webName = g.Key, count = g.Count() });
            var phoneSumRes = VitualPhoneList.GroupBy(v => v.PhoneKind.Name).Select(g => new { webName = g.Key, count = g.Count() });
            foreach (var c in appSumRes)
            {
                appStr += c.webName + ":" + c.count + "条,";
            }
            foreach (var p in phoneSumRes)
            {
                phoneStr += p.webName + ":" + p.count + "个,";
            }
            //end

            Logger.LogInfo(string.Format("开始处理 {0} 总监旗下业务员 {1} 虚拟电话申请",
                director.ToString(), CommonHelper.DateForamt(applyMonth)));
            Logger.LogInfo(string.Format("当前状态:未处理申请 {0}条({1}),\n可分配虚拟电话 {2}个({3})",
                unHandeledList.Count, appStr.TrimEnd(','), VitualPhoneList.Count, phoneStr.TrimEnd(',')));

            //为每条申请匹配一个手机号码
            for (int i = 0; i < unHandeledList.Count; i++)
            {
                CounselorApplication c = unHandeledList[i];
                var isAssignRes = IsAssigned(c);
                if (isAssignRes.Result) //已存在对应关系
                {
                    Logger.Log.Info(c + "该申请对因套餐已存在对应虚拟号码->" + isAssignRes.Message);
                    continue;
                }
                //组织关系检查
                var counselor = counselorManager.GetCounselor(c.CounselorId);
                if (counselor == null)
                {
                    Logger.Log.Error("无法在组织库中获取到该业务员的信息" + c.CounselorId);
                    c.Status = HandlerStatus.人员离职无需处理;
                    UpdateEShopApp(c);
                    continue;
                }

                if (!counselor.IsWorking)
                {
                    Logger.Log.Info("人员离职无需处理" + c.CounselorId);    
                    c.Status = HandlerStatus.人员离职无需处理;
                    UpdateEShopApp(c);
                    continue;
                }
   
                //end

                //TODO 可能需要加上 业务员与区董关系真实性验证
                PhoneKind appPhoneKind = c.PhoneKind;
                HandlerStatus status = c.Status;//申请处理状态 状态 
                VitualPhone phoneModel = VitualPhoneList.Find(v => v.PhoneKind.Id == appPhoneKind.Id);
                if (phoneModel != null)//有号码可分配
                {
                    c.Status = HandlerStatus.分配成功;
                    phoneModel.ActulPhoneNum = c.Mobile;
                    phoneModel.AssignStatus = AssignStatus.已分配;
                    phoneModel.EShopApplyId = c.Id;
                    c.VitualPhone = phoneModel;
                    //Logger.LogInfo(string.Format("成功->业务员 {0} ,{1}", c.CounselorName + " " + c.CounselorId, c.VitualPhone));
                    VitualPhoneList.Remove(phoneModel);//已成功分配的话则从列表中移除该虚拟号码
                    successhandelList.Add(c);
                }
                else //在没号码可分配时记录
                {
                    c.Status = HandlerStatus.无号码可用;
                    UpdateEShopApp(c);
                    // Logger.Log.Error(string.Format("失败->{0}",c.ToString()));
                    continue;
                }
            }
            //持久化数据到数据库 需要事务处理
            this.PersistenceCounselorApplication(successhandelList);
            sp.Stop();
            Logger.LogInfo(string.Format("耗时：{0}处理结束 {1} 总监旗下业务员 {2} 虚拟电话申请",
                sp.Elapsed, director.ToString(), CommonHelper.DateForamt(applyMonth)));
        }
        #endregion

        #region 为某位业务员手动分配虚拟号码
        /// <summary>
        /// 为某位业务员手动分配虚拟号码
        /// </summary>
        public CommResult SingleAssign(string id)
        {
            //TODO 组织架构  总监信息 以及 业务员信息 以及 上下级关系
            CommResult res = new CommResult();
            var newc = this.GetCounselorApplicationById(Convert.ToInt64(id));
            var check = IsAssigned(newc);
            if (check.Result) //已存在
            {
                res.Result = false;
                res.Exception = "已存在对应关系,对应虚拟号码为:" + check.Message + " 申报信息：" + newc;
                return res;
            }
            res = HanlerSingleApp(newc);
            return res;
        }
        #endregion

        #region 处理单独某条申请
        public CommResult HanlerSingleApp(CounselorApplication c)
        {
            var commResult = new CommResult();
            //用于存储成功处理的申请信息列表
            try
            {
                var successhandelList = new List<CounselorApplication>();

                //检查该申请是否已存在对应关系
                var isAssignRes = IsAssigned(c);
                if (isAssignRes.Result)
                {
                    commResult.Result = false;
                    commResult.Exception = c + "该申请对因套餐已存在对应虚拟号码->" + isAssignRes.Message;
                    return commResult;
                }
                //end
                var counselor = counselorManager.GetCounselor(c.CounselorId);
                if (counselor == null)
                {
                    commResult.Result = false;
                    commResult.Exception = "无法在组织库中获取到该业务员的信息";
                    c.Status = HandlerStatus.人员离职无需处理;
                    UpdateEShopApp(c);
                    return commResult;
                }
                if (!counselor.IsWorking)
                {
                    commResult.Result = false;
                    commResult.Exception = "该员工已经离职";
                    c.Status = HandlerStatus.人员离职无需处理;
                    UpdateEShopApp(c);
                    return commResult;
                }
                var director = counselor.Director;

                //获取该区董目前所有可用的虚拟电话
                var VitualPhoneList = directorManager.GetAllUnUsedPhoneList(director.Id).ToList();
                //TODO 可能需要加上 业务员与区董关系真实性验证
                PhoneKind appPhoneKind = c.PhoneKind;
                HandlerStatus status = c.Status;//申请处理状态 状态 
                VitualPhone phoneModel = VitualPhoneList.Find(v => v.PhoneKind.Id == appPhoneKind.Id);
                if (phoneModel != null)//有号码可分配
                {
                    c.Status = HandlerStatus.分配成功;
                    phoneModel.ActulPhoneNum = c.Mobile;
                    phoneModel.AssignStatus = AssignStatus.已分配;
                    phoneModel.EShopApplyId = c.Id;
                    c.VitualPhone = phoneModel;
                    // Logger.LogInfo(string.Format("成功->业务员 {0} ,{1}", c.CounselorName, c.VitualPhone));
                    VitualPhoneList.Remove(phoneModel);//已成功分配的话则从列表中移除该虚拟号码
                    successhandelList.Add(c);
                    var res = PersistenceCounselorApplication(successhandelList);
                    if (res)
                    {
                        commResult.Result = true;
                        commResult.Message = string.Format("成功->业务员 {0} ,{1}", c.CounselorName, c.VitualPhone);
                    }
                }
                else //在没号码可分配时记录
                {
                    c.Status = HandlerStatus.无号码可用;
                    UpdateEShopApp(c);
                    //Logger.Log.Error(string.Format("失败->{0}", c.ToString()));
                    commResult.Result = false;
                    commResult.Exception = string.Format("失败->{0}", c.ToString() + "--无号码可用");
                }
            }
            catch (Exception e)
            {
                commResult.Result = false;
                commResult.Exception = string.Format("失败->{0}", e.ToString());
            }
            return commResult;
        }
        #endregion

        #region 检查某条申请是否已有号码存在对应关系
        /// <summary>
        /// 检查某条申请是否已有号码存在对应关系
        /// </summary>
        /// <param name="c"></param>
        /// <returns>存在对应关系返回true并且返回该虚拟电话对应的真实号码 false表示不存在对应关系</returns>
        public CommResult IsAssigned(CounselorApplication c)
        {
            var res = new CommResult();
            var remoteVitualPhoneList = directorManager.GetAllPhoneListFromTdialnumber(c.Mobile).ToList();//真实号码对应的多个虚拟号码
           // var localVitualPhoneList = directorManager.GetAllPhoneList(c.DirectorId, false).ToList(); //本地虚拟电话池 其包含了电话类别信息
            bool isContains = false;
            string existsVitualPhone = "";
            foreach (var item in remoteVitualPhoneList) //遍历当前已存在对应关系的电话信息
            {
                var localVitualPhoneList = directorManager.GetAllPhoneList(c.DirectorId, false,item.VitualPhoneNum).ToList();
                var p = localVitualPhoneList.Find(lv => lv.VitualPhoneNum == item.VitualPhoneNum && lv.PhoneKind.Id == c.PhoneKind.Id);
                if (p != null)
                {
                    isContains = true;
                    existsVitualPhone = p.VitualPhoneNum;
                    break;
                }
            }
            if (isContains)
            {
                c.Status = HandlerStatus.号码已存在;
                UpdateEShopApp(c);
                res.Result = true;
                res.Message = existsVitualPhone;
            }
            else
            {
                res.Result = false;
                res.Message = "不存在对应关系";
            }
            return res;
        }
        #endregion

        #region 持久化顾问虚拟电话申请
        /// <summary>
        ///持久化顾问虚拟电话申请 ,只有成功分配的 才跟新表 EShopApply
        ///更新表 [VPMS.VitualPhone]- >[AssigneSatus] 
        ///[VPMS.EShopApply] ->[Status]
        ///PhoneRelationship 添加数据
        ///[tdialnumber] 添加数据
        /// </summary>
        /// <returns></returns>
        public bool PersistenceCounselorApplication(List<CounselorApplication> list)
        {
            bool res = true;
            foreach (var ca in list)
            {
                bool t = VitualPhoneDAL.PersistenceCounselorApplicationDAL(ca);
                if (!t)
                {
                    res = t;
                }
                else
                {
                    var logModel = new VitualPhoneLog(ca.DirectorId, ca.DirectorName,ca.CounselorId,ca.CounselorName,ca.Mobile, ca.VitualPhone.VitualPhoneNum, "分配成功",VitualPhoneLogType.添加+"");
                    this.AddVitualPhoneLog(logModel);
                }
            }
            return res;
        }
        #endregion

        #region 初始化总监账号下可用虚拟电话状态 即修正VitualPhone表中数据。如果本地库表VitualPhone表中的虚拟电话在供应商表中没有数据则认为该虚拟号码没有被分配
        /// <summary>
        /// 初始化总监账号下可用虚拟电话状态 即修正VitualPhone表中数据。如果本地库表VitualPhone表中的虚拟电话在供应商表中没有数据则认为该虚拟号码没有被分配
        /// </summary>
        public bool InitalVPStatusOfDirectors()
        {
            Logger.Log.Info("初始化总监账号下可用虚拟电话状态开始");
            Stopwatch sp = new Stopwatch();
            sp.Start();

            bool res = true;
            List<VitualPhone> needToUpdate = new List<VitualPhone>(); //需释放的数据列表
            //从本地库获取已分配的数据  
            List<VitualPhone> localVitualPhoneList = directorManager.GetAllPhoneList().ToList().FindAll(r => r.AssignStatus == AssignStatus.已分配);
            //从供应商标获取数据
            List<VitualPhone> remoteVitualPhoneList = directorManager.GetAllPhoneListFromTdialnumber().ToList();

            if (!localVitualPhoneList.Any()) return true;

            for (int i = 0; i < localVitualPhoneList.Count; i++)
            {
                VitualPhone temp = localVitualPhoneList[i];
                if (!remoteVitualPhoneList.Any(r => r.VitualPhoneNum == temp.VitualPhoneNum))
                {
                    temp.AssignStatus = AssignStatus.未分配;
                    needToUpdate.Add(temp);
                }
            }
            if (needToUpdate.Any())
            {
                UpdateVitualPhoneStatus(needToUpdate);
            }
            sp.Stop();
            Logger.Log.Info("耗时" + sp.Elapsed);
            return res;
        }
        #endregion

        #region 处理远程供应商数据 检查业务为员总监变动，以及离职时 释放虚拟号码: 通过申报表中的电话找到业务员id 检查
        /// <summary>
        /// 
        /// </summary>
        /// <param name="applyMonth">月份</param>
        /// <returns></returns>
        public bool InitalRemoteVitualPhone(DateTime applyMonth)
        {
            Logger.Log.Info("处理远程供应商数据检查业务为员总监变动以及离职时,释放虚拟号码开始");
            Stopwatch sp = new Stopwatch();
            sp.Start();

            bool res = true;
            try
            {
                var needToRealse = new List<VitualPhone>();//用于存储待释放的虚拟号码
                var remoteVitualPhoneList = directorManager.GetAllPhoneListFromTdialnumber().ToList();//当前供应商所以数据
               // var applist = directorManager.GetAllCounselorApplicationList(applyMonth).ToList(); //根据当月所有申请获取员工工号
                foreach (var v in remoteVitualPhoneList)
                {

                    var log = new VitualPhoneLog();
                    var vitualPhonedirector = directorManager.GetDirectorByVp(v.VitualPhoneNum); // 虚拟号所属总监
                    if (vitualPhonedirector == null)
                    {
                        Logger.LogDB.Error("远程供应商数据在本地电话池中未找到数据,可能数据异常,对应虚拟号码： " + v.VitualPhoneNum);
                        continue;
                    }
                    var counselor = counselorManager.GetCounrsorByMobile(v.ActulPhoneNum);
                    if (counselor == null)
                    {
                        string temp = "当月申报表中没有找到,该真实手机号:" + v.ActulPhoneNum + "对应的业务员,释放该虚拟号：" + v.VitualPhoneNum;
                        log.Mark = temp;
                        v.VitualPhoneLog = log;
                        needToRealse.Add(v);
                        Logger.Log.Error(temp);
                        continue;
                    }
                    var director = counselor.Director;
                    if (counselor == null || !counselor.IsWorking || (director.Id != vitualPhonedirector.Id)) //TODO 组织关系异动或者离职
                    {
                        string temp = "";
                        if (!counselor.IsWorking)
                        {
                            temp = "该员工离职状态：" + counselor.Id + " 对应的业务员信息该真实手机号:" + v.ActulPhoneNum + "对应的业务员,释放该虚拟号：" + v.VitualPhoneNum;
                        }

                        if (director != null && director.Id != vitualPhonedirector.Id)
                        {
                            temp = "总监信息异动" + counselor.Id + " 的当前总监:" + director.Id + " 虚拟号码归属总监" + vitualPhonedirector.Id + " 对应的业务员信息该真实手机号:" + v.ActulPhoneNum + "对应的业务员,释放该虚拟号：" + v.VitualPhoneNum;
                        }
                        //解绑  释放总监虚拟电话池  解除供应商对应关系表
                        Logger.Log.Error(temp);
                        log.Mark = temp;
                        v.VitualPhoneLog = log;
                        needToRealse.Add(v);
                    }
                }
                if (needToRealse.Any())
                {
                    needToRealse.ForEach(t => t.AssignStatus = AssignStatus.未分配);
                    UpdateVitualPhoneStatus(needToRealse);
                    ReleaseRemoteNum(needToRealse, applyMonth);
                }
            }
            catch (Exception e)
            {
                Logger.LogDB.Error(e);
                res = false;
            }

            sp.Stop();
            Logger.Log.Info("耗时" + sp.Elapsed);

            return res;
        }
        #endregion

        #region 获取某条申请信息
        /// <summary>
        /// 获取某条申请信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public CounselorApplication GetCounselorApplicationById(Int64 id)
        {
            return VitualPhoneDAL.GetCounselorApplicationByIdDAL(id);
        }
        #endregion

        #region 添加一条申请
        public string AddCounselorApplication(CounselorApplication c)
        {
            return VitualPhoneDAL.AddCounselorApplication(c);
        }
        #endregion

        #region 更新本地数据库中虚拟电话号码状态
        /// <summary>
        /// 更新本地数据库中虚拟电话号码状态
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public void UpdateVitualPhoneStatus(List<VitualPhone> list)
        {
            // return VitualPhoneDAL.UpdateVitualPhoneAssignStatus(model);
            list.ForEach(v => VitualPhoneDAL.UpdateVitualPhoneAssignStatus(v));
        }
        #endregion

        #region 更新本地数据库中某个虚拟电话号码状态
        /// <summary>
        /// 更新本地数据库中虚拟电话号码状态
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool UpdateVitualPhoneStatus(string vitualPhoneNum)
        {
            var vp = new VitualPhone
            {
                VitualPhoneNum = vitualPhoneNum,
                AssignStatus = AssignStatus.未分配
            };
            return VitualPhoneDAL.UpdateVitualPhoneAssignStatus(vp);
        }
        #endregion

        #region 申报表同步
        public bool AsyncCounselorApplicationList(DateTime applyMonth)
        {
            Logger.Log.Info(applyMonth + "申报表数据同步开始");
            Stopwatch sp = new Stopwatch();
            sp.Start();
            bool res = VitualPhoneDAL.AsyncCounselorApplicationListDAL(applyMonth);//数据同步到本地库
            sp.Stop();
            Logger.Log.Info("耗时:" + sp.Elapsed);
            return res;
        }
        #endregion

        #region 号码释放
        /// <summary>
        /// 释放供应商虚拟真实对应关系表
        /// </summary>
        /// <param name="temp"></param>
        public void ReleaseRemoteNum(List<VitualPhone> temp, DateTime applyMonth)
        {
            temp.ForEach(t => ReleaseSingleNum(t,applyMonth));
        }

        /// <summary>
        /// 释放某个虚拟号码
        /// </summary>
        /// <param name="temp"></param>
        public bool ReleaseSingleNum(VitualPhone v, DateTime applyMonth,string reason="")
        {
            bool res = false;
            res = UpdateVitualPhoneStatus(v.VitualPhoneNum);
            if (res)
            {
                if (v.VitualPhoneLog != null && !string.IsNullOrEmpty(v.VitualPhoneLog.Mark))
                {
                    reason += v.VitualPhoneLog.Mark;
                }
                res = VitualPhoneDAL.DeleteFromtdialnumber(v.VitualPhoneNum, reason);

                string directorId = "";
                string directorName = "";
                string counselorId = "";
                string counselorName = "";
                Director dr = directorManager.GetDirectorByVp(v.VitualPhoneNum);
                if (dr != null)
                {
                    directorId = dr.Id;
                    directorName = dr.Name;
                }
      
                var  counselor = counselorManager.GetCounrsorByMobile(v.ActulPhoneNum);
                if (counselor != null)
                {
                    counselorId = counselor.Id;
                    counselorName = counselor.Name;
                }

                var logModel = new VitualPhoneLog(directorId, directorName, counselorId, counselorName, v.ActulPhoneNum, v.VitualPhoneNum, reason, VitualPhoneLogType.释放 + "");
                if (res) this.AddVitualPhoneLog(logModel);
            }
            return res;
        }

        public bool ReleaseSingleNum(string  v,  string reason )
        {
            bool res = false;
            res = UpdateVitualPhoneStatus(v);
            if (res)
            {

                res = VitualPhoneDAL.DeleteFromtdialnumber(v, reason);
                var logModel = new VitualPhoneLog("", "", "", "", "", v, "网站手动释放", VitualPhoneLogType.释放 + "");
                if (res) this.AddVitualPhoneLog(logModel);
            }
            return res;
        }

        #endregion

        #region 更新申请报表状态
        /// <summary>
        /// 更新申报状态
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool UpdateEShopApp(CounselorApplication model)
        {
            return VitualPhoneDAL.UpdateEShopApp(model);
        }
        #endregion

        #region 备份供应商数据到本地
        /// <summary>
        /// 备份供应商数据到本地
        /// </summary>
        /// <returns></returns>
        public bool BackUpdialnumber()
        {
            Logger.Log.Info("备份供应商数据到本地开始");
            Stopwatch sp = new Stopwatch();
            sp.Start();

            try
            {
                DateTime now = DateTime.Now;
                List<VitualPhone> list = VitualPhoneDAL.GetAllPhoneListFromTdialnumberDAL().ToList();//远程数据
                var appList = directorManager.GetAllCounselorApplicationList(now);
                for (int i = 0; i < list.Count; i++)
                {
                    var a = appList.Find(ap => ap.Mobile == list[i].ActulPhoneNum);
                    if (a != null)
                    {
                        list[i].CounselorId = a.CounselorId;
                    }
                }
                list.ForEach(v => VitualPhoneDAL.AddTdialnumberToBak(v, now));
            }
            catch (Exception e)
            {
                Logger.LogDB.Error("备份供应商数据到本地失败", e);
                return false;
            }

            sp.Stop();
            Logger.Log.Info("耗时" + sp.Elapsed);

            return true;
        }
        #endregion

        #region 还原供应商数据到远程表
        /// <summary>
        /// 还原供应商数据到远程表 对应时间点
        /// </summary>
        /// <returns></returns>
        public CommResult Restoredialnumber(DateTime backTime)
        {
            var res = new CommResult();
            try
            {
                List<VitualPhone> list = VitualPhoneDAL.GetBackUpPhoneListFromTdialnumberDAL(backTime).ToList(); //获取备份
                if (list.Any())//存在备份
                {
                    VitualPhoneDAL.ClearTdialnumber();//清空当前供应商数据表
                    list.ForEach(v => VitualPhoneDAL.AddTdialnumber(v));//还原
                    res.Result = true;
                    res.Message = "还原成功";
                }
                else
                {
                    res.Result = false;
                    res.Exception = "备份不存在";
                }
            }
            catch (Exception e)
            {
                Logger.LogDB.Error("备份供应商数据到本地失败", e);
                res.Result = false;
                res.Exception = "备份供应商数据到本地失败";
            }
            return res;
        }
        #endregion

        #region 系统还原
        /// <summary>
        /// 系统还原
        /// </summary>
        /// <param name="backTime"></param>
        /// <param name="appMonth"></param>
        /// <returns></returns>
        public bool RestoreSystem(DateTime backTime, DateTime appMonth)
        {
            try
            {
                Restoredialnumber(backTime);//还原远程数据表
                ClearEShopApply(appMonth); //清空本月申请
                return true;
            }
            catch (Exception e)
            {
                Logger.LogDB.Error("还原失败", e);
                return false;
            }
        }
        #endregion

        #region 清除本地库中当月申报数据 用于系统初始化
        /// <summary>
        /// 清除本地库中当月申报数据 用于系统初始化
        /// </summary>
        /// <param name="appMonth"></param>
        /// <returns></returns>
        public int ClearEShopApply(DateTime appMonth)
        {
            return VitualPhoneDAL.ClearEShopApply(appMonth);
        }
        #endregion

        #region 获取所有备份信息
        public List<BackUpInfo> GetBackUpInfoList()
        {
            return VitualPhoneDAL.GetBackUpInfoList();
        }
        #endregion

        #region 获取网站信息列表
        public List<PhoneKind> GetPhoneKindList()
        {
            return VitualPhoneDAL.GetPhoneKindList();
        }
        #endregion

        #region 获取总监虚拟电话池概要信息
        public List<VitualPhoneDesModel> GetVitualPhoneDesList(DateTime applyMonth, string directorId = null)
        {
            var res = new List<VitualPhoneDesModel>();
            List<Director> directorList = directorManager.GetDirectorInfoListWithVP().ToList();
            if (!string.IsNullOrEmpty(directorId))
            {
                directorList = directorList.FindAll(d => d.Id == directorId);
            }
            foreach (var director in directorList)
            {
                int ajkNeed=0;//当前安居客缺失
                int sfNeed =0;//当前搜房缺失               
                List<CounselorApplication> list = directorManager.GetAllCounselorApplicationList(applyMonth, director.Id).ToList();
                List<CounselorApplication> unHandeledList = list.FindAll(c => c.IsEnabledHandelAgain == true);//可以处理的申请处理状态 
                //获取该区董目前所有可用的虚拟电话
                List<VitualPhone> VitualPhoneList = directorManager.GetAllUnUsedPhoneList(director.Id).ToList();
                ajkNeed = unHandeledList.FindAll(u => u.PhoneKind.Name == "安居客").Count;
                sfNeed = unHandeledList.FindAll(u => u.PhoneKind.Name == "搜房网").Count;
                //数据分析
                string appStr = "";
                string phoneStr = "";
                var appSumRes = unHandeledList.GroupBy(c => c.PhoneKind.Name).Select(g => new { webName = g.Key, count = g.Count() });
                var phoneSumRes = VitualPhoneList.GroupBy(v => v.PhoneKind.Name).Select(g => new { webName = g.Key, count = g.Count() });
                foreach (var c in appSumRes)
                {
                    appStr += c.webName + ":" + c.count + "条,";
                }
                foreach (var p in phoneSumRes)
                {
                    phoneStr += p.webName + ":" + p.count + "个,";
                }
                //end
                string appDes = string.Format("未处理申请 {0}条({1})",
                    unHandeledList.Count, appStr.TrimEnd(','));
                string vitualPhoneDes = string.Format("可分配虚拟电话 {0}个({1})",
                    VitualPhoneList.Count, phoneStr.TrimEnd(','));
                res.Add(new VitualPhoneDesModel
                {
                    Director = director,
                    AppDes = appDes,
                    VitualPhoneDes = vitualPhoneDes,
                    AjkNeed=ajkNeed,
                    SfNeed=sfNeed
                });
            }
            return res;
        }
        #endregion

        #region  添加一条总监虚拟号码
        public CommResult AddVitualPhone(string directorName, string directorId, string vitualPhone, string assigneSatus)
        {
            return VitualPhoneDAL.AddVitualPhoneDAL(directorName, directorId, vitualPhone, assigneSatus);
        }
        #endregion

        #region 添加多条数据
        public CommResult AddVitualPhoneToDB(DataSet ds)
        {
            CommResult res = new CommResult
            {
                Result = true
            };
            int count = 0;
            if (ds != null && ds.Tables.Count > 0)
            {
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    string directorName = dr["DirectorName"].ToString();
                    string directorId = dr["DirectorId"].ToString();
                    string vitualPhone = dr["VitualPhone"].ToString();
                    string assigneSatus = dr["AssigneSatus"].ToString();
                    var temRes = AddVitualPhone(directorName, directorId, vitualPhone, assigneSatus);
                    if (!temRes.Result)
                    {
                        res.Exception += temRes.Exception+"\n";
                        res.Result = false;
                    }
                    else
                    {
                        count++;
                    }
                }
            }
            res.Message = count + "";
            return res;
        }
        #endregion

        #region 添加虚拟电话操作日志信息
        /// <summary>
        /// 添加虚拟电话操作日志信息
        /// </summary>
        /// <returns></returns>
        public bool AddVitualPhoneLog(VitualPhoneLog model)
        {
            return VitualPhoneDAL.AddVitualPhoneLog(model);
        }
        #endregion

        #region 添加数据到本地虚拟电话备份
        public bool AddVitualPhoneBak(DateTime backUpTime, string directorName, string directorId, string vitualPhone,string webName,string mobile, string counselorId, string counselorName)
        {
            return VitualPhoneDAL.AddVitualPhoneBakDAL(backUpTime, directorName, directorId, vitualPhone,webName,mobile, counselorId, counselorName);
        }
        #endregion


        #region 备份供应商数据到本地
        /// <summary>
        /// 备份供应商数据到本地
        /// </summary>
        /// <returns></returns>
        public bool BackUpdVitualPhone()
        {
            Logger.Log.Info("备份本地虚拟电话池数据开始");
            Stopwatch sp = new Stopwatch();
            sp.Start();

            try
            {
                DateTime backUpTime = DateTime.Now;
                List<VitualPhone> list=  directorManager.GetAllPhoneList();
                list.ForEach(l=>AddVitualPhoneBak(backUpTime,l.DirectorName,l.DirectorId,l.VitualPhoneNum,l.PhoneKind.Name,l.ActulPhoneNum,l.CounselorId,l.CounselorName));
            }
            catch (Exception e)
            {
                Logger.LogDB.Error("备份本地虚拟电话池数据开始失败", e);
                return false;
            }

            sp.Stop();
            Logger.Log.Info("耗时" + sp.Elapsed);

            return true;
        }
        #endregion
    }
}
